package com.loong.web.gp4j.service.code;

import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import javax.annotation.Resource;

import org.springframework.stereotype.Service;

import com.loong.web.gp4j.bean.param.code.CodeParam;
import com.loong.web.gp4j.bean.param.code.ExchangeParam;
import com.loong.web.gp4j.bean.schema.code.CodeSchema;
import com.loong.web.gp4j.bean.vo.code.CVo;
import com.loong.web.gp4j.bean.vo.code.CodesVo;
import com.loong.web.gp4j.dao.code.CodeCache;
import com.loong.web.gp4j.dao.code.CodeDao;
import com.loong.web.gp4j.dao.code.CodeTrans;
import com.loong.web.gp4j.service.error.ErrorService;
import com.loong.web.suppert.collection.vo.ResultVo;
import com.loong.web.suppert.collection.vo.ResultVoFactory;

/**
 * 代码服务
 *
 * @author 张成轩
 */
@Service
public class CodeService {

	@Resource
	private CodeDao codeDao;
	@Resource
	private CodeTrans codeTrans;
	@Resource
	private CodeCache codeCache;
	@Resource
	private ErrorService errorService;

	@Resource(name = "code.type")
	private Map<String, String> types;

	/**
	 * 获取代码映射
	 * 
	 * @param type 类型
	 * @return 代码映射
	 */
	public Map<Integer, String> getCodeMap(String type) {

		Map<Integer, String> codes = null;
		// redis是否异常
		boolean redisEx = true;
		try {
			// 获取代码缓存
			codes = codeCache.get(type);
		} catch (RuntimeException e) {
			redisEx = false;
			errorService.error(e);
		}
		if (codes == null) {
			// 查询代码集
			List<CodeSchema> schemas = codeDao.getByType(type);
			codes = CodeAdapter.build(schemas);
			// 保存缓存
			if (redisEx) {
				codeCache.put(type, codes);
			}
		}
		return codes;
	}

	/**
	 * 获取代码类型集
	 * 
	 * @return 代码类型集
	 */
	public List<CodesVo> getCodes() {

		List<CodesVo> vos = new LinkedList<CodesVo>();
		for (Entry<String, String> entry : types.entrySet()) {

			CodesVo vo = new CodesVo();
			vo.setType(entry.getKey());
			vo.setName(entry.getValue());
			vo.setCs(new LinkedList<CVo>());
			vos.add(vo);

			List<CodeSchema> schemas = codeDao.getByType(entry.getKey());
			CodeAdapter.convert(schemas, vo.getCs());
		}
		return vos;
	}

	/**
	 * 获取代码
	 * 
	 * @param id id
	 * @return 返回对象
	 */
	public ResultVo<?> getCode(Integer id) {

		CodeSchema schema = codeDao.get(id);
		if (schema == null)
			return ResultVoFactory.fail("代码不存在");
		CVo vo = new CVo();
		CodeAdapter.convert(schema, vo);
		return ResultVoFactory.succ(vo);
	}

	/**
	 * 新增代码
	 * 
	 * @param param 参数
	 * @return 返回对象
	 */
	public ResultVo<?> add(CodeParam param) {

		CodeSchema code = codeDao.getByTypeAndValue(param.getType(), param.getValue());
		if (code != null)
			return ResultVoFactory.fail("值已存在");
		// 封装对象
		code = new CodeSchema();
		code.setType(param.getType());
		code.setValue(param.getValue());
		code.setName(param.getName());
		// 处理排序问题
		if (param.getBefore() == null) {
			Integer max = codeDao.getMaxOrderByType(param.getType());
			code.setOrder(max == null ? 1 : max + 1);
		} else {
			CodeSchema before = codeDao.get(param.getBefore());
			code.setOrder(before.getOrder());
		}
		// 插入数据
		int count = codeTrans.insert(code);
		if (count != 1)
			return ResultVoFactory.fail("更新失败");
		// 更新缓存
		codeCache.remove(code.getType());
		return ResultVoFactory.succ(code.getId());
	}

	/**
	 * 编辑代码
	 * 
	 * @param param 参数
	 * @return 返回对象
	 */
	public ResultVo<?> edit(CodeParam param) {

		CodeSchema code = codeDao.get(param.getId());
		if (code == null)
			return ResultVoFactory.fail("代码不存在");
		code.setName(param.getName());
		int count = codeDao.update(code);
		if (count != 1)
			return ResultVoFactory.fail("更新失败");
		// 更新缓存
		codeCache.remove(code.getType());
		return ResultVoFactory.succ();
	}

	/**
	 * 移除代码
	 * 
	 * @param id id
	 * @return 返回对象
	 */
	public ResultVo<?> remove(Integer id) {

		CodeSchema code = codeDao.get(id);
		if (code == null)
			return ResultVoFactory.fail("代码不存在");
		int count = codeDao.delete(id);
		if (count != 1)
			return ResultVoFactory.fail("更新失败");
		// 更新缓存
		codeCache.remove(code.getType());
		return ResultVoFactory.succ();
	}

	/**
	 * 交换排序
	 * 
	 * @param param 参数
	 * @return 返回对象
	 */
	public ResultVo<?> exchange(ExchangeParam param) {

		// 查询代码
		CodeSchema code = codeDao.get(param.getId());
		CodeSchema ocode = codeDao.get(param.getOid());
		if (code == null || ocode == null)
			return ResultVoFactory.fail("代码不存在");
		else if (!code.getType().equals(ocode.getType()))
			return ResultVoFactory.fail("代码类型不相同");
		// 交换排序
		Integer o = code.getOrder();
		Integer oo = ocode.getOrder();
		code.setOrder(oo);
		ocode.setOrder(o);
		// 更新数据
		int count = codeTrans.update(code, ocode);
		if (count != 2)
			return ResultVoFactory.fail("更新失败");
		// 更新缓存
		codeCache.remove(code.getType());
		return ResultVoFactory.succ();
	}
}
